home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / login / sac-1.000 / sac-1 / sac-1.3.1 / rawtmp.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  6KB  |  234 lines

  1. /* $Copyright: $
  2.  * Copyright (c) 1995 by Steve Baker (ice@mama.indstate.edu)
  3.  * All Rights reserved
  4.  *
  5.  * This software is provided as is without any express or implied
  6.  * warranties, including, without limitation, the implied warranties
  7.  * of merchant-ability and fitness for a particular purpose.
  8.  */
  9. #include <utmp.h>
  10. #include <ctype.h>
  11. #include <sys/types.h>
  12. #include <sys/time.h>
  13. #include <time.h>
  14. #include <stdio.h>
  15. #include <unistd.h>
  16. #include <fcntl.h>
  17.  
  18. static char *version = "$Version: $ rawtmp v1.2 (c) 1995 by Steve Baker $";
  19.  
  20. #define WTMP  "/etc/wtmp"
  21.  
  22. enum { FALSE=0, TRUE=1 };
  23.  
  24. struct tacacs_utmp {
  25.   char ut_line[8];
  26.   char ut_user[8];
  27.   char ut_host[16];
  28.   time_t ut_time;
  29. };
  30.  
  31. char *num();
  32. time_t getdate(), churn_time();
  33.  
  34. char *start = NULL, *end = NULL, *back = NULL;
  35. time_t sd = 0, ed = 0, backtime = 0, curtime= 0;
  36. int fd;
  37.  
  38. /*
  39.  * rawtmp [-w wtmp] [-t] [-s start] [-e end] [-b hours:minutes:seconds]
  40.  */
  41. main(argc,argv)
  42. int argc;
  43. char **argv;
  44. {
  45.   char *file = WTMP, tacacs = FALSE;
  46.   int i, j, n;
  47.  
  48.   for(n=i=1;i<argc;i=n) {
  49.     n++;
  50.     if (argv[i][0] == '-') {
  51.       for(j=1;argv[i][j];j++) {
  52.     switch (argv[i][j]) {
  53.       case 'w':
  54.         file = argv[n++];
  55.         break;
  56.       case 't':
  57.         tacacs = TRUE;
  58.         break;
  59.       case 'b':
  60.         back = argv[n++];
  61.         break;
  62.       case 's':
  63.         start = argv[n++];
  64.         break;
  65.       case 'e':
  66.         end = argv[n++];
  67.         break;
  68.       case '-':
  69.         if (j == 1) {
  70.           if (!strcmp("--help",argv[i])) usage(4);
  71.         }
  72.       default:
  73.         usage(1);
  74.     }
  75.       }
  76.     } else {
  77.     }
  78.   }
  79.  
  80.   if (start) {
  81.     if (isdigit(start[0])) {
  82.       sd = getdate(start);
  83.     } else usage(2);
  84.   }
  85.   if (end) {
  86.     if (isdigit(end[0])) {
  87.       ed = getdate(end) + 86399;
  88.     } else usage(2);
  89.   }
  90.   if (back) backtime = (curtime=time(0)) - churn_time(back);
  91.  
  92.   fd = open(file,O_RDONLY);
  93.   if (tacacs) doit_tacacs();
  94.   else doit();
  95.   close(fd);
  96. }
  97.  
  98. doit()
  99. {
  100.   static char *ltype[] = {
  101.     "UNKNOWN (0)", "Run Level", "Boot Time", "New Time", "Old Time",
  102.     "INIT Process", "LOGIN Process", "User Process", "Dead Process", NULL
  103.   };
  104.   struct utmp u;
  105.   unsigned char c;
  106.  
  107.   printf("  Time        User    ID  Line         Host               PID   Type\n");
  108.   
  109.   while (read(fd,&u,sizeof(struct utmp)) == sizeof(struct utmp)) {
  110.     if (back && u.ut_time < backtime) continue;
  111.     if (start && u.ut_time < sd) continue;
  112.     if (end && u.ut_time > ed) continue;
  113.     c = u.ut_id[0] & 0x7F;
  114.     u.ut_id[0] = (c && (c > '~' || c < ' '))? '?' : c;
  115.     c = u.ut_id[1] & 0x7F;
  116.     u.ut_id[1] = (c && (c > '~' || c < ' '))? '?' : c;
  117. /*
  118.     printf("%-10ld: %-8.8s [%-2.2s] %-12.12s %-16.16s [%5d] %s\n",
  119.        u.ut_time,u.ut_user,u.ut_id,u.ut_line,u.ut_host,u.ut_pid & 0xFFFF,
  120.        (u.ut_type>0 && u.ut_type<9?ltype[u.ut_type]:num(u.ut_type)));
  121. */
  122.     printf("%-10ld: %-8.8s [%-2.2s] %-12.12s %d.%d.%d.%d [%5d] %s\n",
  123.        u.ut_time,u.ut_user,u.ut_id,u.ut_line,
  124.        u.ut_addr&0xFF,(u.ut_addr>>8)&0xFF,(u.ut_addr>>16)&0xFF,(u.ut_addr>>24)&0xFF,
  125.        u.ut_pid & 0xFFFF,(u.ut_type>0 && u.ut_type<9?ltype[u.ut_type]:num(u.ut_type)));
  126.               
  127.   }
  128. }
  129.  
  130. doit_tacacs()
  131. {
  132.   struct tacacs_utmp u;
  133.   unsigned char c;
  134.  
  135.   printf("  Time        User         Line            Host\n");
  136.  
  137.   while (read(fd,&u,sizeof(struct tacacs_utmp)) == sizeof(struct tacacs_utmp)) {
  138.     if (back && u.ut_time < backtime) continue;
  139.     if (start && u.ut_time < sd) continue;
  140.     if (end && u.ut_time > ed) continue;
  141.  
  142.     printf("%-10ld: %-8.8s  [%-12.12s]  %-16.16s\n",
  143.        u.ut_time,u.ut_user,u.ut_line,u.ut_host);
  144.   }
  145. }
  146.  
  147.  
  148. char *num(n)
  149. unsigned short n;
  150. {
  151.   static char nbuf[30];
  152.  
  153.   sprintf(nbuf,"UNKNOWN (%d)",n);
  154.   return nbuf;
  155. }
  156.  
  157. /*
  158.  * Turn "mm/dd/yy" into time in seconds.
  159.  */
  160. time_t getdate(s)
  161. char *s;
  162. {
  163.   struct tm tm;
  164.   int y;
  165.   time_t t;
  166.  
  167. /*
  168.  * <puke>
  169.  * Need a real date parser that can handle different formats and separators
  170.  */
  171.   if (!isdigit(s[0]) || !isdigit(s[1]) || isdigit(s[2])) usage(2);
  172.   if (!isdigit(s[3]) || !isdigit(s[4]) || isdigit(s[5])) usage(2);
  173.   if (!isdigit(s[6]) || !isdigit(s[7]) || s[8]) usage(2);
  174.  
  175.   tm.tm_mon = atoi(s) -1;
  176.   tm.tm_mday = atoi(s+3);
  177.   y = atoi(s+6);
  178.   tm.tm_year = (y < 70? 100 + y : y);
  179.   tm.tm_isdst = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
  180.  
  181.   t = mktime(&tm);
  182.   if (t == (time_t)(-1)) usage(2);
  183.   return t;
  184. }
  185.  
  186. time_t churn_time(s)
  187. char *s;
  188. {
  189.   time_t t = 0, mult=3600;
  190.   char nbuf[20], p;
  191.  
  192.   for(p=0;*s;s++) {
  193.     if (*s == ':') {
  194.       nbuf[p] = 0;
  195.       t += atoi(nbuf) * mult;
  196.       p = 0;
  197.       if (mult > 1) mult /= 60;
  198.       else usage(3);
  199.     } else if (isdigit(*s)) {
  200.       if (p < 15) nbuf[p++] = *s;
  201.       else usage(3);
  202.     } else usage(3);
  203.   }
  204.   nbuf[p] = 0;
  205.   t += atoi(nbuf) * mult;
  206.  
  207.   return t;
  208. }
  209.  
  210. usage(n)
  211. int n;
  212. {
  213.   switch (n) {
  214.     case 1:
  215.       fprintf(stderr,"usage: rawtmp [-w wtmp] [-t] [-s start] [-e end] [-b H[:M[:S]]]\n");
  216.       break;
  217.     case 2:
  218.       fprintf(stderr,"sac: Invalid date.  Format: mm/dd/yy\n");
  219.       break;
  220.     case 3:
  221.       fprintf(stderr,"sac: Invalid time.  Format: hours[:minutes[:seconds]]\n");
  222.       break;
  223.     case 4:
  224.       fprintf(stderr,"usage: rawtmp [-w wtmp] [-t] [-s start] [-e end] [-b H[:M[:S]]]\n");
  225.       fprintf(stderr,"    -w wtmp     Read alternate wtmp file.\n");
  226.       fprintf(stderr,"    -t          Read old decrepit wtmp format.\n");
  227.       fprintf(stderr,"    -s start    Display accounting info from `start'.\n");
  228.       fprintf(stderr,"    -e end      Display accounting info up to `end'.\n");
  229.       fprintf(stderr,"    -b H:M:S    Show accounting info from the last few hours/minutes/seconds.\n");
  230.       break;
  231.   }
  232.   exit(1);
  233. }
  234.